home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 18 / CU Amiga Magazine's Super CD-ROM 18 (1997)(EMAP Images)(GB)[!][issue 1998-01].iso / CUCD / Magazine / C_Tutorial / Part-6 / asl0.c < prev    next >
C/C++ Source or Header  |  1997-10-27  |  15KB  |  610 lines

  1. #include<exec/libraries.h>
  2. #include<intuition/intuition.h>
  3. #include<utility/tagitem.h>
  4. #include<graphics/text.h>
  5. #include<graphics/rastport.h>
  6. #include<intuition/screens.h>
  7. #include<libraries/gadtools.h>
  8. #include<libraries/asl.h>
  9.  
  10. #include<string.h>
  11. #include<stdio.h>
  12.  
  13. #include<clib/exec_protos.h>
  14. #include<clib/graphics_protos.h>
  15. #include<clib/intuition_protos.h>
  16. #include<clib/gadtools_protos.h>
  17. #include<clib/asl_protos.h>
  18.  
  19. /* The library base global variables */
  20. /* (The different style of opening libraries requires these to be initialised to NULL) */
  21. struct Library* GfxBase = NULL;
  22. struct Library* IntuitionBase = NULL;
  23. struct Library* GadToolsBase = NULL;
  24. struct Library* AslBase = NULL;
  25.  
  26. /* The global handle on the palette gadget */
  27. struct Gadget* palgad = NULL;
  28. /* Global record of foreground pen */
  29. UBYTE pen;
  30. /* Global records of our windows */
  31. struct Window* drawwin = NULL;
  32. struct Window* toolwin = NULL;
  33. /* Global record of title bar height */
  34. int offtop;
  35. /* Global record of our menu strip */
  36. struct Menu* menustrip = NULL;
  37. /* Global record of the screen's visual information */
  38. APTR vinfo = NULL;
  39. /* Initialised structure declaration: describes 8pt Topaz font */
  40. struct TextAttr topazFont = { "topaz.font", 8, 0, 0, };
  41. /* Global record of our gadget list */
  42. struct Gadget* glist = NULL;
  43. /* Global record of our screen */
  44. struct Screen* scr = NULL;
  45. /* Global flag for whether the tool window should be open */
  46. int opentw = TRUE;
  47.  
  48. /* Need to give prototypes for our functions */
  49. int  createAll();
  50. void freeAll();
  51. int  openLibs();
  52. void closeLibs();
  53. int  openScr();
  54. void closeScr();
  55. int  createMenuStrip();
  56. void freeMenuStrip();
  57. int  openToolWin();
  58. void closeToolWin();
  59. int  openDrawWin();
  60. void closeDrawWin();
  61. int  createGadgets();
  62. void freeGadgets();
  63. void handleIDCMP();
  64. int  checkToolWin();
  65. void setFgPen(int);
  66. void doGadgetUp(struct IntuiMessage*);
  67. int  doMenuPick(struct IntuiMessage*);
  68. void load();
  69.  
  70. /* Some constants for the position and size of our gadget */
  71. #define MYBUT_LEFT        (10)
  72. #define MYBUT_TOP            (5)
  73. #define MYBUT_WIDTH        (80)
  74. #define MYBUT_HEIGHT    (12)
  75. #define MYBUT_TEXT        "Next Pen"
  76. #define MYBUT_ID            (0)
  77.  
  78. #define MYPAL_LEFT        (170)
  79. #define MYPAL_TOP            (1)
  80. #define MYPAL_WIDTH        (109)
  81. #define MYPAL_HEIGHT    (19)
  82. #define MYPAL_TEXT        "Colour:"
  83. #define MYPAL_ID            (1)
  84. #define MYPAL_DEPTH        (4)
  85.  
  86. /* The top gap required around the gadgets */
  87. #define MYTOPGAP      (21)
  88.  
  89. /* The initial pen colour */
  90. #define MYINITPEN            (1)
  91.  
  92. /* The start of the program */
  93. void main()
  94. {
  95.     /* Use a different style of opening libraries... */
  96.     if(createAll())
  97.     {
  98.         /* Now do the real work */
  99.         handleIDCMP();
  100.     }
  101.     /* Matched call to close libraries */
  102.     freeAll();
  103. }
  104.  
  105. int createAll()
  106. {
  107.     return openLibs() && openScr() && createMenuStrip() && createGadgets() && openToolWin() && openDrawWin();
  108. }
  109.  
  110. void freeAll()
  111. {
  112.     closeDrawWin();
  113.     closeToolWin();
  114.     freeGadgets();
  115.     freeMenuStrip();
  116.     closeScr();
  117.     closeLibs();
  118. }
  119.  
  120. /* Try to open all the libraries -- return TRUE on success */
  121. int openLibs()
  122. {
  123.     if((GfxBase = OpenLibrary("graphics.library",37)) == NULL)
  124.     {
  125.         printf("Error: could not open graphics.library\n");
  126.         return FALSE;
  127.     }
  128.     if((IntuitionBase = OpenLibrary("intuition.library",37)) == NULL)
  129.     {
  130.         printf("Error: could not open intuition.library\n");
  131.         return FALSE;
  132.     }
  133.     if((GadToolsBase = OpenLibrary("gadtools.library",37)) == NULL)
  134.     {
  135.         printf("Error: could not open gadtools.library\n");
  136.         return FALSE;
  137.     }
  138.     if((AslBase = OpenLibrary("asl.library",37)) == NULL)
  139.     {
  140.         printf("Error: could not open asl.library\n");
  141.         return FALSE;
  142.     }
  143.   return TRUE;
  144. }
  145.  
  146. /* Close any open library */
  147. void closeLibs()
  148. {
  149.     if(AslBase)
  150.         CloseLibrary(AslBase);
  151.     if(GadToolsBase)
  152.         CloseLibrary(GadToolsBase);
  153.     if(IntuitionBase)
  154.         CloseLibrary(IntuitionBase);
  155.     if(GfxBase)
  156.         CloseLibrary(GfxBase);
  157. }
  158.  
  159. /* Open screen and setup GadTools stuff */
  160. int openScr()
  161. {
  162.     UWORD pens[] = { ~0 };
  163.     /* Try to open a new screen with 16 colours (four bitplanes deep) */
  164.     if(scr = OpenScreenTags(NULL,
  165.                                                     SA_Depth,    4,
  166.                                                     /* Enable 3D look by specifying SA_Pens */
  167.                                                     SA_Pens,    pens,
  168.                                                     SA_Title,    "Hello World Painter",
  169.                                                     TAG_DONE))
  170.     {
  171.         /* Get the visual info so GadTools can render the gadgets nicely */
  172.         if(vinfo = GetVisualInfo(scr, TAG_DONE))
  173.             /* Succeeded */
  174.             return TRUE;
  175.         else
  176.             printf("Error: could not get visual info\n");
  177.     }
  178.     else
  179.         printf("Error: could not create screen\n");
  180.     /* Failed */
  181.     return FALSE;
  182. }
  183.  
  184. void closeScr()
  185. {
  186.     if(vinfo)
  187.     {
  188.         FreeVisualInfo(vinfo);
  189.         vinfo = NULL;
  190.     }
  191.     if(scr)
  192.     {
  193.         CloseScreen(scr);
  194.         scr = NULL;
  195.     }
  196. }
  197.  
  198. /* Create the menu strip, using GadTools menu functions */
  199. int createMenuStrip()
  200. {
  201.     /* The description of our menus */
  202.     struct NewMenu mymenu[] =
  203.     {
  204.         { NM_TITLE, "Project",            0,        0, 0, 0,},
  205.         {  NM_ITEM,        "Load",                "L",    0, 0, 0,},
  206.         {  NM_ITEM,        NM_BARLABEL,    0,        0, 0, 0,},
  207.         {  NM_ITEM,        "Quit",                "Q",    0, 0, 0,},
  208.         { NM_TITLE, "Pen",                    0,        0, 0, 0,},
  209.         {  NM_ITEM,        "Next",                "N",    0, 0, 0,},
  210.         {  NM_ITEM,        "Prev",                "P",    0, 0, 0,},
  211.         {  NM_ITEM,        NM_BARLABEL,    0,        0, 0, 0,},
  212.         {  NM_ITEM,        "Reset",            "R",    0, 0, 0,},
  213.         { NM_TITLE, "Tools",                0,        0, 0, 0,},
  214.         {  NM_ITEM,        "Screen Bar",    "C",    CHECKIT | MENUTOGGLE | CHECKED, 0, 0,},
  215.         {  NM_ITEM,        "Tool Bar",        "T",    CHECKIT | MENUTOGGLE | CHECKED, 0, 0,},
  216.         {   NM_END, NULL,                        0,        0, 0, 0,},
  217.     };
  218.     if (menustrip = CreateMenus(mymenu, TAG_END))
  219.     {
  220.         if (LayoutMenus(menustrip, vinfo, TAG_END))
  221.             /* Succeeded */
  222.             return TRUE;
  223.         else
  224.             printf("Error: could not layout menus\n");
  225.     }
  226.     else
  227.         printf("Error: could not create menu strip\n");
  228.     /* Failed */
  229.     return FALSE;
  230. }
  231.  
  232. void freeMenuStrip()
  233. {
  234.     if(menustrip)
  235.     {
  236.         FreeMenus(menustrip);
  237.         menustrip = NULL;
  238.     }
  239. }
  240.  
  241. /* Actually open the windows, in the normal way */
  242. int openToolWin()
  243. {
  244.     /* Extra protection -- only open if not already open */
  245.     if(toolwin == NULL)
  246.     {
  247.         /* The minimal height of our tool window */
  248.         int h = MYTOPGAP + offtop + scr->WBorBottom;
  249.         /* Open our tool window */
  250.         if(toolwin = OpenWindowTags(NULL,
  251.                                                                 WA_Left,                    0,
  252.                                                                 WA_Top,                        scr->Height - h,
  253.                                                                 /* Make the window sit in the bottom of the screen */
  254.                                                                 WA_Width,                    scr->Width,
  255.                                                                 WA_Height,                h,
  256.                                                                 WA_Flags,                    WFLG_CLOSEGADGET | WFLG_DRAGBAR,
  257.                                                                 WA_IDCMP,                    IDCMP_CLOSEWINDOW | BUTTONIDCMP | IDCMP_REFRESHWINDOW | IDCMP_MENUPICK,
  258.                                                                 WA_Gadgets,                glist,
  259.                                                                 WA_CustomScreen,    scr,
  260.                                                                 WA_Title,                    "Tools",
  261.                                                                 TAG_DONE,                    0))
  262.         {
  263.             /* Attach menu strip to tool window, as well */
  264.             if(SetMenuStrip(toolwin, menustrip))
  265.             {
  266.                 /* Let GadTools refresh its bits of the tool window */
  267.                 GT_RefreshWindow(toolwin, NULL);
  268.                 return TRUE;
  269.             }
  270.             else
  271.                 printf("Error: could not attach menus to tool window\n");
  272.         }
  273.         else
  274.             printf("Error: could not open tool window\n");
  275.     }
  276.     else
  277.         printf("Warning: tool window already open\n");
  278.     return FALSE;
  279. }
  280.  
  281. void closeToolWin()
  282. {
  283.     if(toolwin)
  284.     {
  285.         ClearMenuStrip(toolwin);
  286.         CloseWindow(toolwin);
  287.         toolwin = NULL;
  288.     }
  289. }
  290.  
  291. int openDrawWin()
  292. {
  293.     /* Open our drawing window */
  294.     if(drawwin = OpenWindowTags(NULL,
  295.                                                             WA_Left,                    0,
  296.                                                             WA_Top,                        0,
  297.                                                             /* Make the window the same size as the screen */
  298.                                                             WA_Width,                    scr->Width,
  299.                                                             WA_Height,                scr->Height,
  300.                                                             WA_Flags,                    WFLG_BACKDROP | WFLG_BORDERLESS | WFLG_REPORTMOUSE,
  301.                                                             WA_IDCMP,                    IDCMP_MOUSEBUTTONS | IDCMP_MOUSEMOVE | IDCMP_MENUPICK,
  302.                                                             WA_CustomScreen,    scr,
  303.                                                             TAG_DONE,                    0))
  304.     {
  305.         /* Set the drawing mode to draw only the foreground of text, not the background */
  306.         SetDrMd(drawwin->RPort, JAM1);
  307.         /* Attach menu strip to drawing window */
  308.         if(SetMenuStrip(drawwin, menustrip))
  309.             return TRUE;
  310.         else
  311.             printf("Error: could not attach menus to drawing window\n");
  312.     }
  313.     else
  314.         printf("Error: could not open drawing window\n");
  315.     return FALSE;
  316. }
  317.  
  318. void closeDrawWin()
  319. {
  320.     if(drawwin)
  321.     {
  322.         ClearMenuStrip(drawwin);
  323.         CloseWindow(drawwin);
  324.         drawwin = NULL;
  325.     }
  326. }
  327.  
  328. int createGadgets()
  329. {
  330.     struct Gadget* gad;
  331.     int offleft;
  332.     struct NewGadget newgad;
  333.     /* Start a GadTools gadget list */
  334.     gad = CreateContext(&glist);
  335.     /* The offsets of our window borders */
  336.     offleft = scr->WBorLeft;
  337.     offtop = scr->WBorTop + (scr->Font->ta_YSize + 1);
  338.  
  339.     /* Setup our first gadget */
  340.     newgad.ng_TextAttr         = &topazFont;
  341.     newgad.ng_VisualInfo     = vinfo;
  342.     newgad.ng_LeftEdge         = MYBUT_LEFT + offleft;
  343.     newgad.ng_TopEdge         = MYBUT_TOP + offtop;
  344.     newgad.ng_Width             = MYBUT_WIDTH;
  345.     newgad.ng_Height             = MYBUT_HEIGHT;
  346.     newgad.ng_GadgetText    = MYBUT_TEXT;
  347.     newgad.ng_GadgetID        = MYBUT_ID;
  348.     newgad.ng_Flags                = 0;
  349.     /* Now create it and add it to our list */
  350.     gad = CreateGadget(BUTTON_KIND, gad, &newgad, TAG_END);
  351.  
  352.     /* Setup our second gadget */
  353.     /* (We can reuse newgad, and just change the different bits) */
  354.     newgad.ng_LeftEdge         = MYPAL_LEFT + offleft;
  355.     newgad.ng_TopEdge         = MYPAL_TOP + offtop;
  356.     newgad.ng_Width             = MYPAL_WIDTH;
  357.     newgad.ng_Height             = MYPAL_HEIGHT;
  358.     newgad.ng_GadgetText    = MYPAL_TEXT;
  359.     newgad.ng_GadgetID        = MYPAL_ID;
  360.     newgad.ng_Flags                = 0;
  361.     /* Now create it and add it to our list */
  362.     gad = CreateGadget(    PALETTE_KIND, gad, &newgad,
  363.                                             /* Initially selected pen */
  364.                                             GTPA_Color, MYINITPEN,
  365.                                             /* Depth: 2 to the power MYPAL_DEPTH colours */
  366.                                             GTPA_Depth, MYPAL_DEPTH,
  367.                                             /* Gadget will indicate selection */
  368.                                             GTPA_IndicatorWidth, 16,
  369.                                             TAG_DONE);
  370.  
  371.     /* Remember gadget pointer so we can affect it in message handler */
  372.     palgad = gad;
  373.     /* Success if we managed final allocation */
  374.     return (gad != NULL);
  375. }
  376.  
  377. void freeGadgets()
  378. {
  379.     if(glist)
  380.     {
  381.         FreeGadgets(glist);
  382.         glist = NULL;
  383.         /* Reset palgad pointer, too */
  384.         palgad = NULL;
  385.     }
  386. }
  387.  
  388. /* Our message handling code */
  389. void handleIDCMP()
  390. {
  391.     char* text = "Hello World!";
  392.     int going = TRUE;
  393.     int drawing = FALSE;
  394.     ULONG drawsig, toolsig, gotsig;
  395.     drawsig = 1 << drawwin->UserPort->mp_SigBit;
  396.     setFgPen(MYINITPEN);
  397.     while(going)
  398.     {
  399.         struct IntuiMessage* intuimsg;
  400.         /* Only include tool window signal mask if window is open */
  401.         toolsig = opentw ? 1 << toolwin->UserPort->mp_SigBit : 0;
  402.         /* Wait for messages to arrive */
  403.         gotsig = Wait(drawsig | toolsig);
  404.         /* Messages have arrived: loop through all of them */
  405.         /* Check messages from the drawing window first */
  406.         if(gotsig & drawsig)
  407.         {
  408.             while(intuimsg = GT_GetIMsg(drawwin->UserPort))
  409.             {
  410.                 /* Act on this message... */
  411.                 switch(intuimsg->Class)
  412.                 {
  413.                 case IDCMP_MOUSEBUTTONS:
  414.                     switch(intuimsg->Code)
  415.                     {
  416.                     case SELECTDOWN:
  417.                         drawing = TRUE;
  418.                         break;
  419.                     case SELECTUP:
  420.                         drawing = FALSE;
  421.                         break;
  422.                     }
  423.                     /* break; omitted so we draw on click, too */
  424.                 case IDCMP_MOUSEMOVE:
  425.                     if(drawing)
  426.                     {
  427.                         Move(drawwin->RPort, intuimsg->MouseX, intuimsg->MouseY);
  428.                         Text(drawwin->RPort, text, strlen(text));
  429.                     }
  430.                     break;
  431.                 case IDCMP_MENUPICK:
  432.                     going = doMenuPick(intuimsg);
  433.                     break;
  434.                 }
  435.                 /* Reply when finished with message */
  436.                 GT_ReplyIMsg(intuimsg);
  437.             }
  438.         }
  439.         /* Now check messages from the tool window */
  440.         if(going && (gotsig & toolsig))
  441.         {
  442.             while(intuimsg = GT_GetIMsg(toolwin->UserPort))
  443.             {
  444.                 /* Act on this message... */
  445.                 switch(intuimsg->Class)
  446.                 {
  447.                 case IDCMP_CLOSEWINDOW:
  448.                     {
  449.                         struct MenuItem* item;
  450.                         opentw = FALSE;
  451.                         /* Unset menu check mark */
  452.                         /* First, remove menu strip from windows */
  453.                         ClearMenuStrip(drawwin);
  454.                         ClearMenuStrip(toolwin);
  455.                         /* Menu 2, Item 1 is Tool Bar */
  456.                         item = ItemAddress(menustrip, FULLMENUNUM(2,1,0));
  457.                         /* Unset CHECKED flag */
  458.                         item->Flags &= ~CHECKED;
  459.                         /* Reattach menu strip to windows */
  460.                         ResetMenuStrip(toolwin,menustrip);
  461.                         ResetMenuStrip(drawwin,menustrip);
  462.                         break;
  463.                     }
  464.                 case IDCMP_REFRESHWINDOW:
  465.                     /* You *MUST* remember to ask for and handle these refresh messages */
  466.                     GT_BeginRefresh(toolwin);
  467.                     GT_EndRefresh(toolwin, TRUE);
  468.                     break;
  469.                 case IDCMP_GADGETUP:
  470.                     doGadgetUp(intuimsg);
  471.                     break;
  472.                 case IDCMP_MENUPICK:
  473.                     going = doMenuPick(intuimsg);
  474.                     break;
  475.                 }
  476.                 /* Reply when finished with message */
  477.                 GT_ReplyIMsg(intuimsg);
  478.             }
  479.         }
  480.         /* Check tool window if still going */
  481.         if(going)
  482.             going = checkToolWin();
  483.     }
  484. }
  485.  
  486. /* Check whether tool window should be opened or closed */
  487. int checkToolWin()
  488. {
  489.     if(toolwin)
  490.     {
  491.         if(!opentw)
  492.             closeToolWin();
  493.     }
  494.     else
  495.     {
  496.         if(opentw && !openToolWin())
  497.              return FALSE;  /* Error! Re-open failed */
  498.     }
  499.     return TRUE;
  500. }
  501.  
  502. /* Set foreground pen of drawing window */
  503. void setFgPen(int value)
  504. {
  505.     /* Wrap when reached the end of the palette gadget's colours */
  506.     pen = value % (1<<MYPAL_DEPTH);
  507.     /* Only set pen if window is open */
  508.     if(drawwin)
  509.         SetAPen(drawwin->RPort, pen);
  510.     /* If the palette gadget has been made, update it with new pen value */
  511.     if(palgad)
  512.         GT_SetGadgetAttrs(palgad, toolwin, NULL, GTPA_Color, pen, TAG_DONE);
  513. }
  514.  
  515. /* Process IDCMP_GADGETUP event */
  516. void doGadgetUp(struct IntuiMessage* intuimsg)
  517. {
  518.     struct Gadget* gad = (struct Gadget*)(intuimsg->IAddress);
  519.     switch(gad->GadgetID)
  520.     {
  521.     case MYBUT_ID:
  522.         /* Our button was clicked!  Set foreground to next pen colour */
  523.         setFgPen(pen+1);
  524.         break;
  525.     case MYPAL_ID:
  526.         /* Our palette gadget was clicked!  Set foreground to gadget colour */
  527.         setFgPen(intuimsg->Code);
  528.         break;
  529.     }
  530. }
  531.  
  532. /* Process IDCMP_MENUPICK event */
  533. int doMenuPick(struct IntuiMessage* intuimsg)
  534. {
  535.     UWORD menuCode, menuNumber, itemNumber;
  536.     /* Loop over all the menu selections in the menu code */
  537.     struct MenuItem* item;
  538.     for(menuCode = intuimsg->Code;
  539.             menuCode != MENUNULL;
  540.             menuCode = item->NextSelect)
  541.     {
  542.         item = ItemAddress(menustrip, menuCode);
  543.         /* Extract the menu number and menu item number from the menu code */
  544.         menuNumber = MENUNUM(menuCode);
  545.         itemNumber = ITEMNUM(menuCode);
  546.         /* Now decide what to do based on what menu item was selected */
  547.         switch(menuNumber)
  548.         {
  549.         case 0:  /* Project menu */
  550.             /* Only one item: Quit */
  551.             switch(itemNumber)
  552.             {
  553.             case 0:  /* Load */
  554.                 load();
  555.                 break;
  556.             case 2:  /* Quit (item 1 is the bar!) */
  557.                 return FALSE;
  558.             }
  559.             break;
  560.         case 1:  /* Pen menu */
  561.             switch(itemNumber)
  562.             {
  563.             case 0:  /* Next */
  564.                 setFgPen(pen+1);
  565.                 break;
  566.             case 1:  /* Prev */
  567.                 setFgPen(pen-1);
  568.                 break;
  569.             case 3:  /* Reset (item 2 is the bar!) */
  570.                 setFgPen(MYINITPEN);
  571.                 break;
  572.             }
  573.             break;
  574.         case 2:  /* Tools menu */
  575.             switch(itemNumber)
  576.             {
  577.             case 0:  /* Screen Bar */
  578.                 ShowTitle(scr, item->Flags & CHECKED);
  579.                 break;
  580.             case 1:  /* Tool Bar */
  581.                 /* Set state to indicate whether the tool window should be open */
  582.                 opentw = (item->Flags & CHECKED);
  583.                 break;
  584.             }
  585.         }
  586.     }
  587.     /* Keep going */
  588.     return TRUE;
  589. }
  590.  
  591. /* Open an ASL load file requester */
  592. void load()
  593. {
  594.     struct FileRequester* freq;
  595.     if(freq = (struct FileRequester*)AllocAslRequest(ASL_FileRequest,NULL))
  596.     {
  597.         if(AslRequestTags(freq,
  598.                                             ASLFR_TitleText,            "Load File",
  599.                                             ASLFR_Window,                    drawwin,
  600.                                             ASLFR_Flags1,                    FRF_DOPATTERNS,
  601.                                             ASLFR_InitialPattern,    "#?.iff",
  602.                                             TAG_DONE))
  603.         {
  604.             /* Directory is in freq->rf_Dir, file in freq->rf_File */
  605.         }
  606.         /* ..else request was cancelled */
  607.         FreeAslRequest(freq);
  608.     }
  609. }
  610.